package com.fa4j.common.web.util;

import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

@Slf4j
public class IpUtil {

    private static final String[] IP_REQUEST_HEADER_NAMES = new String[]{"X-Forwarded-For", "Proxy-Client-IP",
            "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR", "X-Real-IP"
    };

    /**
     * 获取本地IPv4
     *
     * @return IPv4
     */
    public static String getLocalIPv4() {
        StringBuilder localIps = new StringBuilder();
        try {
            Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
            while (netInterfaces.hasMoreElements()) {
                NetworkInterface ni = netInterfaces.nextElement();
                // if (!ni.isUp() || ni.isLoopback() || ni.isVirtual()) continue;
                if (ni.isUp() && !ni.isLoopback() && !ni.isVirtual()) {
                    Enumeration<InetAddress> inetAddresses = ni.getInetAddresses();
                    while (inetAddresses.hasMoreElements()) {
                        InetAddress inetAddress = inetAddresses.nextElement();
                        if (inetAddress instanceof Inet4Address) {
                            String localIp = inetAddress.getHostAddress();
                            if (!localIps.isEmpty()) {
                                localIps.append("/");
                            }
                            localIps.append(localIp);
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("检查任务执行的机器IP时发生错误", e);
        }
        return localIps.toString();
    }

    /**
     * 获取客户端ip
     */
    public static String getRemoteIp() {
        if (!(RequestContextHolder.currentRequestAttributes() instanceof ServletRequestAttributes requestAttributes)) {
            return null;
        }
        HttpServletRequest request = requestAttributes.getRequest();
        for (String ipHeaderName : IP_REQUEST_HEADER_NAMES) {
            String ip = request.getHeader(ipHeaderName);
            if (ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip)) {
                if (ip.contains(",")) {
                    ip = ip.substring(0, ip.indexOf(","));
                }
                log.debug("{} ip: {}", ipHeaderName, ip);
                return ip;
            }
        }
        String ip = request.getRemoteAddr();
        log.trace("getRemoteAddr ip: {}", ip);
        return ip;
    }
}
